package com.skb.web.controller;

import com.skb.core.model.*;
import com.skb.core.model.controller.AccountModel;
import com.skb.core.service.IAccountService;
import com.skb.core.service.ISegmentService;
import com.skb.core.service.IUserService;
import com.skb.utils.JsonPagedDataAction;
import com.skb.utils.SysLookup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.SerializationUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
public class AdminAccountController {

    @Autowired
    private IAccountService accountService;

    @Autowired
    private IUserService userService;

    @Autowired
    private ISegmentService segmentService;

    private String msg;

    private String error;

    @Transactional(readOnly = true)
    @RequestMapping(value = "admin/account/getAccountsList", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
    public @ResponseBody JsonPagedDataAction<AccountModel> getAccountsList(HttpSession session) {
        JsonPagedDataAction<AccountModel> data = new JsonPagedDataAction<AccountModel>() {};

        List<AccountModel> list = new ArrayList<>();
        for (Account account : accountService.findAll()) {
            AccountModel am = new AccountModel();
            am.setNumber(account.getNumber());
            am.setBalance(account.getBalance());
            am.setUsername(account.getUser().getUsername());
            am.setSegment(account.getSegment().getName());
//            am.setSegmentObj(account.getSegment());
            User user = new User();
            user.setFirstName(account.getUser().getFirstName());
            user.setLastName(account.getUser().getLastName());
            am.setUser(user);
            list.add(am);
        }

        data.setData(list);
        return data;
    }

    @RequestMapping(value = {"/admin/account/accounts" }, method = RequestMethod.GET)
    public ModelAndView showAccounts(HttpSession session){
        ModelAndView model = new ModelAndView();
        model.addObject("msg", msg);
        model.addObject("error", error);
        msg = "";
        error = "";
        model.setViewName("admin/account/accounts");
        return model;
    }

    public ModelAndView editAccount() {
        ModelAndView model = new ModelAndView();

        return model;
    }

    @RequestMapping(value = {"/admin/account/deleteAccount" }, method = RequestMethod.GET)
    public ModelAndView deleteAccount(@RequestParam(value="number", required=true) String number) {
        ModelAndView model = new ModelAndView();
        if (number != null && !number.trim().isEmpty()) {
            Account account = accountService.get(number);
            if (account != null) {
                accountService.delete(account);
                msg = "Konto usunięto poprawnie";
            } else {
                error = "Niepoprawne usuwanie";
            }
        } else {
            error = "Niepoprawne usuwanie";
        }
        model.setViewName("redirect:/admin/account/accounts");
        return model;
    }

    @RequestMapping(value = {"/admin/account/cashWithdrawal" }, method = RequestMethod.GET)
    public ModelAndView cashWithdrawal(@RequestParam(value="number", required=true) String number) {
        ModelAndView model = new ModelAndView();
        if (number != null && !number.trim().isEmpty()) {
            Account account = accountService.get(number);
            if (account != null) {
                account.setBalance(account.getBalance() - 1000);
                accountService.update(account);
                msg = "Wypłacono poprawnie";
            } else {
                error = "Niepoprawne dane";
            }
        } else {
            error = "Niepoprawne dane";
        }
        model.setViewName("redirect:/admin/account/accounts");
        return model;
    }

    @RequestMapping(value = {"/admin/account/cachePayment" }, method = RequestMethod.GET)
    public ModelAndView cachePayment(@RequestParam(value="number", required=true) String number) {
        ModelAndView model = new ModelAndView();
        if (number != null && !number.trim().isEmpty()) {
            Account account = accountService.get(number);
            if (account != null) {
                account.setBalance(account.getBalance() + 1000);
                accountService.update(account);
                msg = "Wpłacono poprawnie";
            } else {
                error = "Niepoprawne dane";
            }
        } else {
            error = "Niepoprawne dane";
        }
        model.setViewName("redirect:/admin/account/accounts");
        return model;
    }

    @Transactional
    @RequestMapping(value = {"/admin/account/nextMonth" }, method = RequestMethod.GET)
    public ModelAndView nextMonth(HttpSession session) {
        ModelAndView model = new ModelAndView();

        List<Account> accounts = accountService.findAll();
        for (Account account : accounts) {
            Segment segment = segmentService.get(account.getSegment().getId());
            CommissionRate commissionRate = segment.getCommissionRate();
            InterestRate interestRate = segment.getInterestRate();

            Double balance = account.getBalance();
            balance -= commissionRate.getAccountManagmentFee();
            balance -= commissionRate.getCardFee();
            balance -= commissionRate.getiBankFee();
            if (balance > 0) {
                balance = balance + (balance * (interestRate.getAccountInterest()/100.0/12.0));
            }
            DecimalFormat formatter = new DecimalFormat("#########.00");
            account.setBalance(Double.parseDouble(formatter.format(balance).replace(",",".")));
            accountService.update(account);
        }

        model.setViewName("admin/account/accounts");
        return model;
    }


//    @RequestMapping(value = "wf/getFormList", method = RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
//    public @ResponseBody JsonPagedDataAction<ModelFormDefinition> getFormDefinitionList(HttpSession session) {
//        JsonPagedDataAction<ModelFormDefinition> data = new JsonPagedDataAction<ModelFormDefinition>() {};
//        String department = (String) session.getAttribute(SysLookup.SessionKey.DEPARTMENTS);
//        List<Map<String, String>> listForms = orbeonDao.getForms(department);
//
//        List<ModelFormDefinition> list = new ArrayList<>();
//
//        for (Map<String, String> map : listForms) {
//            list.add(new ModelFormDefinition(
//                    map.get(SysLookup.OrbeonColums.DEFINITION_APP),
//                    map.get(SysLookup.OrbeonColums.DEFINITION_FORM),
//                    SysLookup.DEPARTMENT.valueOf(map.get(SysLookup.OrbeonColums.DEFINITION_APP)).getDescription(),
//                    map.get(SysLookup.OrbeonColums.DEFINITION_LAST_MODIFIED_BY)));
//        }
//        data.setData(list);
//        return data;
//    }

//    @RequestMapping(value = {"/wf/forms" }, method = RequestMethod.GET)
//    public ModelAndView showForms() {
//        ModelAndView model = new ModelAndView();
//        model.setViewName("wf/forms");
//        return model;
//    }

//    @RequestMapping(value = {"/wf/archiveTask" }, method = RequestMethod.GET)
//    public ModelAndView archiveTask(@RequestParam(value="task", required=true) Integer id) {
//        ModelAndView model = new ModelAndView();
//        PetroOilDoc doc = petroOilDocService.get(id);
//
//        if (doc == null) {
//            error = "Nie ma takiego dokumentu.";
//        } else {
//            doc.setDepartment(SysLookup.DEPARTMENT.ARCHIVE.toString());
//            petroOilDocService.update(doc);
//            msg = "Przeniesiono do archiwum.";
//        }
//        model.setViewName("redirect:/wf/tasks");
//        return model;
//    }

//    @RequestMapping(value = {"/wf/removeTask" }, method = RequestMethod.GET)
//    public ModelAndView removeTask(@RequestParam(value="task", required=true) Integer id) {
//        ModelAndView model = new ModelAndView();
//        PetroOilDoc doc = petroOilDocService.get(id);
//
//        if (doc == null) {
//            error = "Nie ma takiego dokumentu.";
//        } else {
//            doc.setDepartment(SysLookup.DEPARTMENT.TRASH.toString());
//            petroOilDocService.update(doc);
//            msg = "Przeniesiono do kosza.";
//        }
//        model.setViewName("redirect:/wf/tasks");
//        return model;
//    }

//    @RequestMapping(value = {"/wf/doTask" }, method = RequestMethod.GET)
//    public ModelAndView doTask(@RequestParam(value="task", required=true) Integer id, HttpSession session) {
//        ModelAndView model = new ModelAndView();
//        String department = (String) session.getAttribute(SysLookup.SessionKey.DEPARTMENTS);
//        PetroOilDoc doc = petroOilDocService.get(id);
//        WorkflowRule rule = workflowRuleService.getRuleByFormAndDep(doc.getForm(), department);
//
//        if (doc == null || rule == null || rule.getFlows() == null || rule.getFlows().isEmpty()) {
//            error = "Brak takiego dokumentu lub nie ma zdefiniowanego workflow dla tego dokumentu";
//            model.setViewName("redirect:/wf/tasks");
//            return model;
//        }
//
//        model.addObject("flowsMap", flowsMap(rule.getFlows()));
//        model.addObject("doc", doc);
//        model.setViewName("wf/doTask");
//        return model;
//    }

//    @RequestMapping(value = {"/wf/saveDoneTask" }, method = RequestMethod.POST)
//    public ModelAndView saveWorkflowRuleList(@ModelAttribute("doc") PetroOilDoc doc) {
//        ModelAndView model = new ModelAndView();
//        PetroOilDoc petroOilDoc = null;
//
//        if (doc.getDocumentId() != null) {
//            petroOilDoc = petroOilDocService.get(doc.getDocumentId());
//        } else if (petroOilDoc == null) {
//            error = "Nie ma takiego dokumentu.";
//            model.setViewName("redirect:/wf/tasks");
//        }
//
//
//        doc.setDescription(doc.getDescription());
//        doc.setForm(petroOilDoc.getForm());
//        doc.setUsername(petroOilDoc.getUsername());
//        doc.setOrbeonDocId(petroOilDoc.getOrbeonDocId());
//        petroOilDocService.update(doc);
//
//        msg = "Zadanie zostało poprawnie przekazane dalej.";
//        model.setViewName("redirect:/wf/tasks");
//        return model;
//    }
//

//    private Map<String, String> flowsMap(String flows) {
//        Map<String, String> map = new HashMap<>();
//        for (String s : SysListUtils.stringToList(flows)) {
//            SysLookup.DEPARTMENT dep = SysLookup.DEPARTMENT.valueOf(s);
//            if (dep != null) {
//                map.put(dep.toString(), dep.getDescription());
//            }
//        }
//        return map;
//    }
}
